import { useState, useCallback, useRef } from 'react';
import { Upload, X, File, Play, AlertCircle } from 'lucide-react';
import { clsx } from 'clsx';
import { useAppDispatch } from '@/store';
import { addFile, setUploadProgress } from '@/store/slices/videoSlice';
import { showToast } from '@/store/slices/uiSlice';
import { videoService } from '@/services/video';
import { formatFileSize } from '@/utils/format';
import './styles.less';

interface FileUploaderProps {
  accept?: string;
  multiple?: boolean;
  maxSize?: number; // in bytes
  maxFiles?: number;
  onFilesSelected?: (files: File[]) => void;
  disabled?: boolean;
  className?: string;
}

interface FileWithPreview extends File {
  id: string;
  preview?: string;
  progress?: number;
  error?: string;
}

export const FileUploader: React.FC<FileUploaderProps> = ({
  accept = 'video/*',
  multiple = true,
  maxSize = 500 * 1024 * 1024, // 500MB
  maxFiles = 10,
  onFilesSelected,
  disabled = false,
  className,
}) => {
  const dispatch = useAppDispatch();
  const fileInputRef = useRef<HTMLInputElement>(null);

  const [isDragOver, setIsDragOver] = useState(false);
  const [selectedFiles, setSelectedFiles] = useState<FileWithPreview[]>([]);
  const [isProcessing, setIsProcessing] = useState(false);

  const validateFile = (file: File): string | null => {
    if (!videoService.validateVideoFile(file)) {
      return '不支持的文件格式';
    }

    if (file.size > maxSize) {
      return `文件大小超过限制 (${formatFileSize(maxSize)})`;
    }

    return null;
  };

  const processFiles = async (files: FileWithPreview[]) => {
    setIsProcessing(true);

    for (const file of files) {
      try {
        dispatch(setUploadProgress(0));

        // 模拟上传进度
        for (let progress = 0; progress <= 100; progress += 10) {
          await new Promise(resolve => setTimeout(resolve, 100));
          dispatch(setUploadProgress(progress));
          setSelectedFiles(prev => prev.map(f => (f.id === file.id ? { ...f, progress } : f)));
        }

        // 获取视频信息
        const videoInfo = await videoService.getVideoInfo(URL.createObjectURL(file));

        if (videoInfo.success && videoInfo.data) {
          dispatch(
            addFile({
              ...videoInfo.data,
              id: file.id,
              name: file.name,
              size: file.size,
            })
          );

          dispatch(
            showToast({
              type: 'success',
              title: '文件添加成功',
              message: `${file.name} 已添加到处理队列`,
            })
          );
        }
      } catch (error) {
        setSelectedFiles(prev =>
          prev.map(f =>
            f.id === file.id
              ? {
                  ...f,
                  error: error instanceof Error ? error.message : '处理失败',
                }
              : f
          )
        );

        dispatch(
          showToast({
            type: 'error',
            title: '文件处理失败',
            message: `${file.name}: ${error instanceof Error ? error.message : '未知错误'}`,
          })
        );
      }
    }

    setIsProcessing(false);
    dispatch(setUploadProgress(0));
  };

  const handleFileSelect = useCallback(
    (files: FileList | File[]) => {
      const fileArray = Array.from(files);
      const currentCount = selectedFiles.length;

      if (currentCount + fileArray.length > maxFiles) {
        dispatch(
          showToast({
            type: 'error',
            title: '文件数量超限',
            message: `最多只能选择 ${maxFiles} 个文件`,
          })
        );
        return;
      }

      const validFiles: FileWithPreview[] = [];

      for (const file of fileArray) {
        const error = validateFile(file);
        const fileWithPreview: FileWithPreview = Object.assign(file, {
          id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
          progress: 0,
          error: error || undefined,
        });

        if (!error) {
          // 为视频文件生成预览
          if (file.type && file.type.startsWith('video/')) {
            const video = document.createElement('video');
            video.preload = 'metadata';
            video.onloadedmetadata = () => {
              video.currentTime = Math.min(video.duration * 0.1, 5); // 10% or 5s
            };
            video.onseeked = () => {
              const canvas = document.createElement('canvas');
              canvas.width = 160;
              canvas.height = 90;
              const ctx = canvas.getContext('2d');
              if (ctx) {
                ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
                fileWithPreview.preview = canvas.toDataURL();
                setSelectedFiles(prev =>
                  prev.map(f => (f.id === fileWithPreview.id ? fileWithPreview : f))
                );
              }
            };
            video.src = URL.createObjectURL(file);
          }
        }

        validFiles.push(fileWithPreview);
      }

      setSelectedFiles(prev => [...prev, ...validFiles]);
      onFilesSelected?.(validFiles.filter(f => !f.error));

      // 自动处理有效文件
      const filesToProcess = validFiles.filter(f => !f.error);
      if (filesToProcess.length > 0) {
        processFiles(filesToProcess);
      }
    },
    [selectedFiles.length, maxFiles, maxSize, dispatch, onFilesSelected]
  );

  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      setIsDragOver(false);

      if (disabled) return;

      const files = e.dataTransfer.files;
      handleFileSelect(files);
    },
    [handleFileSelect, disabled]
  );

  const handleDragOver = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      if (!disabled) {
        setIsDragOver(true);
      }
    },
    [disabled]
  );

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragOver(false);
  }, []);

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      handleFileSelect(e.target.files);
    }
  };

  const handleRemoveFile = (fileId: string) => {
    setSelectedFiles(prev => prev.filter(f => f.id !== fileId));
  };

  const handleSelectFiles = () => {
    if (!disabled) {
      fileInputRef.current?.click();
    }
  };

  const getTotalSize = () => {
    return selectedFiles.reduce((total, file) => total + file.size, 0);
  };

  const getValidFiles = () => {
    return selectedFiles.filter(f => !f.error);
  };

  return (
    <div className={clsx('file-uploader', className)}>
      {/* Drop Zone */}
      <div
        className={clsx(
          'file-uploader__dropzone',
          isDragOver && 'file-uploader__dropzone--drag-over',
          disabled && 'file-uploader__dropzone--disabled'
        )}
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onClick={handleSelectFiles}
      >
        <div className='file-uploader__dropzone-content'>
          <div className='file-uploader__icon'>
            <Upload className='w-12 h-12' />
          </div>

          <div className='file-uploader__text'>
            <h3>拖拽文件到此处或点击选择</h3>
            <p>
              支持 MP4, AVI, MOV, MKV 等视频格式
              <br />
              单文件最大 {formatFileSize(maxSize)}，最多 {maxFiles} 个文件
            </p>
          </div>

          <button type='button' className='btn-primary' disabled={disabled}>
            选择文件
          </button>
        </div>
      </div>

      {/* Hidden File Input */}
      <input
        ref={fileInputRef}
        type='file'
        accept={accept}
        multiple={multiple}
        onChange={handleInputChange}
        className='file-uploader__input'
        disabled={disabled}
      />

      {/* File List */}
      {selectedFiles.length > 0 && (
        <div className='file-uploader__files'>
          <div className='file-uploader__files-header'>
            <h4>已选择的文件 ({selectedFiles.length})</h4>
            <div className='file-uploader__files-info'>
              总大小: {formatFileSize(getTotalSize())} | 有效文件: {getValidFiles().length}
            </div>
          </div>

          <div className='file-uploader__files-list'>
            {selectedFiles.map(file => (
              <div
                key={file.id}
                className={clsx(
                  'file-uploader__file-item',
                  file.error && 'file-uploader__file-item--error'
                )}
              >
                <div className='file-uploader__file-preview'>
                  {file.preview ? (
                    <img src={file.preview} alt='' />
                  ) : (
                    <div className='file-uploader__file-icon'>
                      {file.type && file.type.startsWith('video/') ? (
                        <Play className='w-6 h-6' />
                      ) : (
                        <File className='w-6 h-6' />
                      )}
                    </div>
                  )}
                </div>

                <div className='file-uploader__file-info'>
                  <div className='file-uploader__file-name'>{file.name}</div>
                  <div className='file-uploader__file-meta'>
                    {formatFileSize(file.size)} | {file.type || 'Unknown type'}
                  </div>

                  {file.error && (
                    <div className='file-uploader__file-error'>
                      <AlertCircle className='w-4 h-4' />
                      {file.error}
                    </div>
                  )}

                  {file.progress !== undefined && file.progress > 0 && file.progress < 100 && (
                    <div className='file-uploader__file-progress'>
                      <div className='file-uploader__progress-bar'>
                        <div
                          className='file-uploader__progress-fill'
                          style={{ width: `${file.progress}%` }}
                        />
                      </div>
                      <span>{file.progress}%</span>
                    </div>
                  )}
                </div>

                <button
                  type='button'
                  onClick={() => handleRemoveFile(file.id)}
                  className='file-uploader__file-remove'
                  disabled={isProcessing}
                >
                  <X className='w-4 h-4' />
                </button>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

export default FileUploader;
